package com.ribbon.user;

import com.netflix.hystrix.HystrixCollapser;
import com.netflix.hystrix.HystrixCollapserKey;
import com.netflix.hystrix.HystrixCollapserProperties;
import com.netflix.hystrix.HystrixCommand;
import com.ribbon.User;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by qhe on 2018/7/27.
 */
public class UserCollapseCommand extends HystrixCollapser<List<User>,User,Long> {

    private UserService userService;

    private Long userId;

    public UserCollapseCommand(UserService userService,Long userId){
        super(Setter.withCollapserKey(HystrixCollapserKey.Factory.asKey("userBatchCommand")).andCollapserPropertiesDefaults(
                HystrixCollapserProperties.Setter().withTimerDelayInMilliseconds(100)//设置时间延迟属性
        ));
        this.userService = userService;
        this.userId = userId;
    }

    @Override
    public Long getRequestArgument() {
        return userId;
    }

    /**
     *collection参数中保存了延迟时间窗中收集到的所有获取单个User的请求。
     * 通过获取这些请求的参数来组织上面我们准备的批量请求命令UserBatchCommand实例
     * @param collection
     * @return
     */
    @Override
    protected HystrixCommand<List<User>> createCommand(Collection<CollapsedRequest<User, Long>> collection) {
        List<Long> userIds = new ArrayList<>(collection.size());
        userIds.addAll(collection.stream().map(CollapsedRequest::getArgument).collect(Collectors.toList()));
        return new UserBatchCommand(userService,userIds);
    }

    /**
     * 在批量请求命令UserBatchCommand实例被触发执行完成之后，该方法开始执行，
     * 其中users中保存了creatCommand方法中组织的批量请求命令的返回结果，
     * 而collection参数则代表了每个被合并的请求，
     * 在这里我们通过遍历批量结果users对象，为collection中每个合并前的单个请求设置返回结果，
     * 完成批量结果到单个请求结果的转换
     * @param users
     * @param collection
     */
    @Override
    protected void mapResponseToRequests(List<User> users, Collection<CollapsedRequest<User, Long>> collection) {
        int count = 0;
        for (CollapsedRequest<User,Long> collapsedRequest:collection){
            User user = users.get(count++);
            collapsedRequest.setResponse(user);
        }
    }






















}
